#!/usr/bin/env python

import sys
import re
import os
import stat
import subprocess

libs = []
maps = []

def getlibandaddr2line(address):

   result = 'lib?|function?'
   for map in maps:
      maparea = (re.search(r'[0-9a-f]+-[0-9a-f]+', map)).group()
      mapareas = maparea.split('-')

      if int(address, 16) >= int(mapareas[0], 16) and int(address, 16) < int(mapareas[1], 16) :

         for lib in libs:
            print lib
            if os.path.basename(map.split()[5]) in lib:
               cmd = 'addr2line -s -f -p -C' + ' -e ' + lib + ' -a ' + hex(int(address, 16) - int(mapareas[0], 16))
               sys.stderr.write('cmd=%s\n' % cmd)

               addr2line = subprocess.check_output(cmd, shell = True).replace('\n', ''). split(': ')[1]
               return os.path.basename(map.split()[5]) + '|' + addr2line
               break
         break

   return result

def main():

   if len(sys.argv) == 4:

      #build maps from tdi
      #DSC 0 0 MAPS,741b1000-74213000,r-xp,00000000,00:10,56754894,,,/lib/libuClibc-0.9.32.1.so
      f = open(sys.argv[1])
      for line in f:
         if 'DSC 0 0 MAPS' in line:
            l = line[13:].replace(',',' ')
            if l not in maps:
               maps.append(l)
      f.close()
      #print maps

      #build libs
      for root, dirs, files in os.walk(sys.argv[2]):
         for file in files:
            if '/' + file + '\\n' in str(maps):
               if 'MIPS' in subprocess.check_output('file ' + root + '/' + file, shell = True):
               #if os.access(fpath, os.X_OK)
               #if os.path.isfile(root + '/' + file):
                  if not root + '/' + file in libs:
                     libs.append(root + '/' + file)

      #for l in libs:
      #   print l

      print getlibandaddr2line(sys.argv[3])

   else:

      print("Usage: %s tdifile pathtorootfs hexaddress" % sys.argv[0])

if __name__ == "__main__":
   main()
